package com.ubxtech.cloud.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ubxtech.cloud.client.MsgPushClient;
import com.ubxtech.cloud.properties.CloudProperties;
import com.ubxtech.core.context.ContextConstants;
import com.ubxtech.core.context.ContextUtil;
import com.ubxtech.db.annotation.IgnoreTenant;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import feign.Target;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import jakarta.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 *
 * @author Victor.Xiao
 * @since 2022-01-17 19:42
*/
@Slf4j
public class FeignAddHeaderRequestInterceptor implements RequestInterceptor {

    private String origin;
    private String greyVersion;
    private CloudProperties cloudProperties;
    public FeignAddHeaderRequestInterceptor(String origin,String greyVersion,CloudProperties cloudProperties) {
        this.origin = origin;
        this.greyVersion = greyVersion;
        this.cloudProperties = cloudProperties;
    }

    /** 愿意是只有这些请求头能传递,但目前没有这个需求 */
    public static final List<String> HEADER_NAME_LIST = Arrays.asList(
            ContextConstants.TOKEN
            , ContextConstants.USER_ID
            , ContextConstants.USERNAME
            , ContextConstants.NICKNAME
            , ContextConstants.HEADER_AREA_LIST
            , ContextConstants.HEADER_ADMIN_FLAG
            , ContextConstants.HEADER_REAL_IP
            , ContextConstants.HEADER_FORWARDED_FOR
            , ContextConstants.X_TRACE_ID
            , ContextConstants.TRACE_ID
            , ContextConstants.CLIENT_ID
            , ContextConstants.HEADER_APP_ID
            , ContextConstants.HEADER_SIGN
            , ContextConstants.HEADER_DEVICE_ID
            , ContextConstants.KEY_TENANT
            , ContextConstants.KEY_TENANT_MULTI
            , ContextConstants.HEADER_GRAY_VERSION_NAME
            , ContextConstants.API_VERSION_NAME
            , ContextConstants.HEADER_LANG
            , ContextConstants.HEADER_LANGUAGE
            , ContextConstants.HEADER_PERMISSION
            , ContextConstants.HEADER_USER_AGENT
//            , ContextConstants.HEADER_CONTENT_LENGTH
//            , ContextConstants.HEADER_CONTENT_TYPE//请求类型和长度不能传递,feign接口类型可能不一样,比如get调用post的接口
    );


    @Override
    public void apply(RequestTemplate template) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = null;
        if (attributes != null) {
            request = attributes.getRequest();
        }
        for (String headerName : HEADER_NAME_LIST) {
            String headerValue = "";
            if (request != null) {
                headerValue = request.getHeader(headerName);
            }
            //优先已有的,主要是要解析出token和user_id信息
            headerValue = StrUtil.isEmpty(headerValue) ? URLUtil.encode(ContextUtil.get(headerName,String.class,"")) : headerValue;
            if (StrUtil.isNotBlank(headerValue)) {
                template.header(headerName, headerValue);
            }
            //处理内部直接client调用的情况,这种情况没有经过filter,不会设置version,如果是灰度版本,请求头也为空,则用本地的设置
            else if (ContextConstants.HEADER_GRAY_VERSION_NAME.equalsIgnoreCase(headerName) && StrUtil.isNotBlank(greyVersion)) {
                template.header(ContextConstants.HEADER_GRAY_VERSION_NAME, greyVersion);
                //用本地的greyVersion
                ContextUtil.setGrayVersion(greyVersion);
            }
        }
        if (StrUtil.isNotBlank(origin)) {
            template.header(ContextConstants.HEADER_ORIGIN, origin);
        }
        Method method = template.methodMetadata().method();
        IgnoreTenant methodIgnoreTenant = method.getAnnotation(IgnoreTenant.class);
        if (methodIgnoreTenant != null) {
            //feign接口也支持忽略租户
            template.header(ContextConstants.HEADER_IGNORE_TENANT, "1");
        }
        template.header(ContextConstants.P_TRACE_ID, URLUtil.encode(ContextUtil.getXTraceId()));
        template.header(ContextConstants.TRACE_ID, URLUtil.encode(ContextUtil.get(ContextConstants.TRACE_ID, String.class, "")));
        //当前的不传递,下游生成新的
        template.header(ContextConstants.X_TRACE_ID, "");

        //处理消息逻辑,只有下发消息才需要获取消息类型
        Target<?> target = template.feignTarget();
        ContextUtil.set("msgType", "");
        //只有推消息的这个client才处理
        if (target.type().getName().equals(MsgPushClient.class.getName())) {
            if (template.body() != null && template.body().length > 0) {
                //获取body,拿到msgType
                String body = new String(template.body());
                if (StrUtil.isNotBlank(body)) {
                    JSONObject bodyJson = JSONObject.parseObject(body);
                    Integer type = bodyJson.getInteger("type");
                    String topic = bodyJson.getString("topic");
                    if (type != null && StrUtil.isNotBlank(topic)) {
                        ContextUtil.set("msgType", String.valueOf(type));
                        ContextUtil.set("msgTopic", topic);
                    }
                }
            }
        }
    }


//    @Override
//    public void apply(RequestTemplate template) {
//        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//        if (attributes == null) {
//            HEADER_NAME_LIST.forEach(headerName -> template.header(headerName, URLUtil.encode(ContextUtil.get(headerName,String.class,""))));
//            if (StrUtil.isNotBlank(origin)) {
//                template.header(ContextConstants.HEADER_ORIGIN, origin);
//            }
//            return;
//        }
//        Method method = template.methodMetadata().method();
//        IgnoreTenant methodIgnoreTenant = method.getAnnotation(IgnoreTenant.class);
//        if (methodIgnoreTenant != null) {
//            //fein接口也支持忽略租户
//            template.header(ContextConstants.HEADER_IGNORE_TENANT, "1");
//        }
//        if (StrUtil.isNotBlank(origin)) {
//            template.header(ContextConstants.HEADER_ORIGIN, origin);
//        }
//        HttpServletRequest request = attributes.getRequest();
//        HEADER_NAME_LIST.forEach((headerName) -> {
//            String headerValue = request.getHeader(headerName);
//            if (ContextConstants.X_TRACE_ID.equalsIgnoreCase(headerName)) {
//                template.header(ContextConstants.P_TRACE_ID, URLUtil.encode(ContextUtil.getXTraceId()));
//                //当前的不传递,下游生成新的
//                template.header(ContextConstants.X_TRACE_ID, "");
//                return;
//            }
//            template.header(headerName, ObjectUtil.isEmpty(headerValue) ? URLUtil.encode(ContextUtil.get(headerName,String.class,"")) : headerValue);
//        });
//
//
//    }
}
